package com.hoshiicloud.saleorder.mq;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.hoshiicloud.common.api.dto.EncryptedResponseDTO;
import com.hoshiicloud.common.constant.OrderInfoStatusEnum;
import com.hoshiicloud.common.constant.OrderMainStatusEnum;
import com.hoshiicloud.common.constant.PayStatusEnum;
import com.hoshiicloud.common.constant.QueueConsts;
import com.hoshiicloud.common.constant.OrderInfoServiceStatusEnum;
import com.hoshiicloud.common.constant.enumeration.Channel;
import com.hoshiicloud.common.exception.ServiceException;
import com.hoshiicloud.common.rpc.Response;
import com.hoshiicloud.common.utils.EncryptionUtil;
import com.hoshiicloud.saleorder.entity.OrderInfo;
import com.hoshiicloud.saleorder.entity.OrderMain;
import com.hoshiicloud.saleorder.entity.Payorder;
import com.hoshiicloud.saleorder.dto.ExtSkuDTO;
import com.hoshiicloud.saleorder.dto.PoBillDTO;
import com.hoshiicloud.saleorder.feign.GoodsService;
import com.hoshiicloud.saleorder.service.OrderInfoService;
import com.hoshiicloud.saleorder.service.OrderMainService;
import com.hoshiicloud.saleorder.service.PayorderService;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @program: hoshiicloud
 * @description: rabmitMQ消息消费业务处理
 * @author: Mr.wu
 * @create: 2019-06-01 15:15
 **/
@Slf4j
@Component
public class RabbitMQConsumer {

    /**
     * 子订单业务服务层
     */
    @Autowired
    private OrderInfoService orderInfoService;
    /**
     * 主订单业务服务层
     */
    @Autowired
    private OrderMainService orderMainService;
    /**
     * 支付订单业务服务层
     */
    @Autowired
    private PayorderService payorderService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * 支付成功回调消息处理
     *
     * @param message
     * @throws Exception
     */
    @RabbitListener(queues = QueueConsts.PAY_CALLBACK_QUEUE)
    @RabbitHandler
    public void payCallBackprocess(Message message) {
        try {
            log.info("接受回调消息" + message.toString());
            //获取请求体转换
            String body = new String(message.getBody());
            log.info("body:" + body);
            System.out.println(body);
            String json = new String(Base64.getMimeDecoder().decode(body.replace("\r\n", "")));
            Map<String, String> data = EncryptionUtil
                    .decryptData(json, RsaConfig.getClientPublicKey(),
                            RsaConfig.getServerPrivateKey());
            if (data == null) {
                //验签失败
                throw new ServiceException("解析消息失败，验签失败");
            } else {
                // id: paylist的主键
                // orderId: 支付订单id
                // platformId: 下单时传入的merId

                log.info("支付流水id：" + data.get("id"));
                // 支付订单
                log.info("orderId：" + data.get("orderId"));
                log.info("merId：" + data.get("platformId"));
                log.info("channel：" + data.get("channel"));
                String orderId = data.get("orderId");
                Long paylistId = Long.valueOf(data.get("id"));
                int channel = Integer.parseInt(data.get("channel"));

                //修改支付订单 销售订单 销售订单子单状态
                this.payCallOrderHandle(paylistId, orderId, channel);
            }
            //业务处理
        } catch (Exception e) {
            log.error("{}", e.getMessage());
        }

    }

    /**
     * 采购订单回调消息处理
     *
     * @param message
     * @throws Exception
     */
    @RabbitListener(queues = QueueConsts.PUSH_PO_QUEUE)
    @RabbitHandler
    public void poCallBackprocess(Message message) {
        try {
            log.info("接受回调消息{}", message.toString());
            //获取请求体转换
            String body = new String(message.getBody());
            log.info("body:" + body);
            System.out.println(body);
            String json = new String(Base64.getMimeDecoder().decode(body.replace("\r\n", "")));
            Map<String, String> data = EncryptionUtil
                    .decryptData(json, RsaConfig.getClientPublicKey(),
                            RsaConfig.getServerPrivateKey());
            PoBillDTO dto = EncryptionUtil.decryptData(json, RsaConfig.getClientPublicKey(),
                    RsaConfig.getServerPrivateKey(), PoBillDTO.class);
            log.info("data:" + JSON.toJSONString(data));
            //业务处理
        } catch (Exception e) {
            log.error("{}", e.getMessage());
        }
    }

    /**
     * 推送销售主订单至采购中心
     */
    //    @Async
    public void pushSoToPo(Set<Long> orderMainIdSet) {
        //推送消息生成采购订单
        // todo 后续继续完善业务代码
        new Thread(() -> {
            try {
                EncryptedResponseDTO encryptData = EncryptionUtil
                        .encryptData(orderMainIdSet, RsaConfig.getClientPrivateKey(),
                                RsaConfig.getServerPublicKey());
                String data = JSON.toJSONString(encryptData);
                String base64Info = Base64.getEncoder().encodeToString(data.getBytes());
                rabbitTemplate.convertAndSend(QueueConsts.PUSH_PO_QUEUE, base64Info);
            } catch (Exception e) {
                log.error("{}", e.getMessage());
            }
        }).start();
        //        try {
        //            EncryptedResponseDTO encryptData = EncryptionUtil
        //                    .encryptData(OrderMainIdSet, RsaConfig.getClientPrivateKey(),
        //                            RsaConfig.getServerPublicKey());
        //            String data = JSON.toJSONString(encryptData);
        //            String base64Info = Base64.getEncoder().encodeToString(data.getBytes());
        //            rabbitTemplate.convertAndSend(QueueConsts.PUSH_PO_QUEUE, base64Info);
        //        } catch (Exception e) {
        //            e.printStackTrace();
        //        }
        //        //推送消息生成采购订单
        //        // todo 后续继续完善业务代码
        //        threadPoolExecutor.execute(() -> {
        //
        //        });
    }

    /**
     * 支付回调 订单处理
     */
    private void payCallOrderHandle(Long paylistId, String orderId, int channel) {
        //支付订单id
        if (orderId != null) {
            Long payOrderId = Long.valueOf(orderId);
            Payorder payorder = payorderService.getById(payOrderId);
            if (    payorder != null
                    && PayStatusEnum.UN_PAID.getCode() == payorder.getStatus()) {//状态为未支付
                List<OrderInfo> orderInfoList = orderInfoService.listByPayOrderId(payOrderId);
                if (CollectionUtils.isNotEmpty(orderInfoList)) {
                    payorder.setUpdatedBy("admin")
                            .setPayListId(paylistId)
                            .setPayTime(LocalDateTime.now())
                            .setUpdatedTime(LocalDateTime.now())
                            .setStatus(PayStatusEnum.HAS_PAID.getCode());
                    payorderService.updateById(payorder);

                    //主单ID集合
                    Set<Long> orderMainIdSet = new HashSet<>();
                    for (OrderInfo orderInfo : orderInfoList) {
                        //修改子订单状态及付款时间
                        //订单状态 待发货
                        orderInfo.setOrderStatus(OrderInfoStatusEnum.WAIT_EXTRACT_GOODS.getCode())
                                //支付状态 已付款
                                .setPayStatus(PayStatusEnum.HAS_PAID.getCode())
                                .setServiceStatus(OrderInfoServiceStatusEnum.CAN_AFTER_SALE.getCode())
                                .setPaidTime(LocalDateTime.now());
                        orderInfoService.updateById(orderInfo);
                        orderMainIdSet.add(orderInfo.getMainId());
                    }

                    //修改主订单状态及时间
                    for (Long mainId : orderMainIdSet) {
                        // 主订单id
                        OrderMain om =orderMainService.getById(mainId);
                                //支付方式名称
                                om.setPayName(Objects.requireNonNull(Channel.getByChannel(channel)).getPayName())
                                //订单状态 待发货
                                .setOrderStatus(OrderMainStatusEnum.WAIT_EXTRACT.getCode())
                                //支付状态 已付款
                                .setPayStatus(PayStatusEnum.HAS_PAID.getCode())
                                .setServiceStatus(OrderInfoServiceStatusEnum.CAN_AFTER_SALE.getCode())
                                //付款时间
                                .setPaidTime(LocalDateTime.now());
                        orderMainService.updateById(om);

                    }
                    //推送主订单信息列表到采购服务,采购服务中做采购策略判断
                    pushSoToPo(orderMainIdSet);

                }
            }
        }

    }

    /**
     * 采购处理
     */
    private void purchaseProcess(OrderInfo orderInfo) {
        /**
         * 根据子订单的skuid获取商品属性
         * 根据商品属性中的供应商进行采购处理
         * 如果供应商是租户或平台,不生成采购单
         * 如果指定了供应商但库存不足，生成库存异常单
         * 如果没有指定供应商，则找到最优供货价的供应商，然后判断库存是否充足，如果库存<采购数，则寻找供货价其次的供应商，再判断库存是否充足，直到找到库存充足的供货商为止，如果没有找到，走异常流程
         */
        Response<ExtSkuDTO> result = goodsService.getExtSku(orderInfo.getSkuId());
        ExtSkuDTO goodInfo = result.getData();
    }

}
